package com.yuyu.commons.config.db;

import com.yuyu.commons.toolKit.PropertiesUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.util.*;

/**
 * @author
 * @version 1.0
 * @description: 动态加载配置文件并放入propertiesUtil的容器中
 * 因为spring中也有默认的PostProcessor，并且最后一个的order为Integer.MIN_VALUE+10,所以我们自定义的postProcesssor可以从Integer.MIN_VALUE+10之后开始排序。
 * @date 2022/12/5 10:37
 */
public class DbConfig implements EnvironmentPostProcessor, Ordered {

    private Logger logger = LogManager.getLogger();
    private static final Integer POST_PROCESSOR_ORDER = Integer.MIN_VALUE+10;


    @SuppressWarnings(value = {"unchecked","rawtypes"})
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        MutablePropertySources propertySources = environment.getPropertySources();
        //获取激活的配置文件
        String[] activeProfiles = environment.getActiveProfiles();
        Properties activeConfigs = getConfig(activeProfiles);
        propertySources.addLast(new PropertiesPropertySource("actConfigs",activeConfigs));
        for (PropertySource<?> propertySource : propertySources) {
            //是键值对的properties才放入propertiesUtils工具中
            if (propertySource.getSource() instanceof Map){
                Map sourceMap =(Map) propertySource.getSource();
                sourceMap.forEach((k,v)->{
                    //存入工具类中
                    PropertiesUtil.getProperties().put(k.toString(),v.toString());
                });
            }
        }
    }

    @Override
    public int getOrder() {
        return DbConfig.POST_PROCESSOR_ORDER+1;
    }

    /**
     * 获取配置文件
     * @param activeProfiles
     * @return
     */
    private Properties getConfig(String[] activeProfiles){
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        List<Resource> resourceList = new ArrayList<>();
        getResource(resolver,resourceList,"classpath*:/*.properties");
        getResource(resolver,resourceList,"classpath*:/*.yml");
        getResource(resolver,resourceList,"classpath*:/log.config");
        if (Objects.nonNull(activeProfiles)){
            for (String profiles : activeProfiles) {
                String p =  "classpath*:/config/"+profiles+"/*.properties";
                getResource(resolver,resourceList,p);
            }
        }
        try {
            //spring properties管理对象  将properties加载处理进ioc
            PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
            propertiesFactoryBean.setLocations(resourceList.toArray(new Resource[]{}));
            propertiesFactoryBean.afterPropertiesSet();
            return propertiesFactoryBean.getObject();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据path
     */
    private void getResource(PathMatchingResourcePatternResolver resolver,List<Resource> resourceList,String path){
        try {
            Resource[] resources = resolver.getResources(path);
            for (Resource resource : resources) {
                resourceList.add(resource);
                logger.info("exists:{},URL:{},URI:{},contentLength:{},isFile:{}",
                        resource.exists(), resource.getURL(),
                        resource.getURI(),resource.contentLength(),
                        resource.isFile());
            }
        }catch (Exception e){
            logger.error("",e);
        }
    }
}
